#include <buola/net/cxmlrpcstruct.h>
#include <buola/net/cxmlrpcarray.h>
#include <buola/net/cxmlrpccall.h>

namespace buola { namespace io {

CXMLRPCStruct::CXMLRPCStruct()
{
}
    
CXMLRPCStruct::CXMLRPCStruct(CXMLRPCCall &pCall)
    :   mStruct(pCall.XML().NewNode("struct"))
{
}

CXMLRPCStruct::CXMLRPCStruct(xml::CNode pStruct)
    :   mStruct(pStruct)
{
}

void CXMLRPCStruct::AddItem(const std::string &pName,const std::string &pValue)
{
    xml::CNode lMember=mStruct.NewChild("member");
    lMember.NewChild("name",pName);
    lMember.NewChild("value").NewChild("string",pValue);
}

void CXMLRPCStruct::AddItem(const std::string &pName,double pValue)
{
    xml::CNode lMember=mStruct.NewChild("member");
    lMember.NewChild("name",pName);
    lMember.NewChild("value").NewChild("string",to_string(pValue));
}

void CXMLRPCStruct::GetItem(const std::string &pName,std::string &pValue)
{
    xml::CNode lValue=GetItem(pName);
    if(!lValue.MatchesName("string")) throw XInvalid("wrong type in XML_RPC struct");
    pValue=lValue.Content();
}

void CXMLRPCStruct::GetItem(const std::string &pName,CXMLRPCArray &pValue)
{
    xml::CNode lValue=GetItem(pName);
    if(!lValue.MatchesName("array")) throw XInvalid("wrong type in XML_RPC struct");
    pValue=CXMLRPCArray(lValue);
}

xml::CNode CXMLRPCStruct::GetItem(const std::string &pName)
{
    for(auto lChild : mStruct.Children())
    {
        if(lChild.MatchesName("member")&&lChild.FirstChild("name").Content()==pName)
        {
            xml::CNode lValue=lChild.FirstChild("value");
            if(!lValue.FirstChild()) throw XInvalid("wrong format in XML-RPC struct");
            return lValue.FirstChild();
        }
    }
    throw XNotFound("item not found in XML-RPC struct");
}

/*namespace io*/ } /*namespace buola*/ }
